package ui
{
	import flash.events.MouseEvent;
	import events.GCEvent;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.text.TextField;
	
	/**
	 * A ui component made of four slots, in which the numbers of each
	 * slot can be manipulated up to a maximum value that can be changed
	 * later.
	 */
	public class GCNumberScroller extends Sprite
	{
		public static const MAX_VALUE:int = 9999;
		
		private var _value:int;
		private var _newValue:int;
		
		private var _onesPlace:GCNumberScrollPart;
		private var _tensPlace:GCNumberScrollPart;
		private var _hundredsPlace:GCNumberScrollPart;
		private var _thousandsPlace:GCNumberScrollPart;
		
		private var _limit:int;
		
		/**
		 * Constructor
		 */
		public function GCNumberScroller()
		{
			super();
			
			_value = 0;
			_newValue = 0;
			_limit = MAX_VALUE;
			
			_onesPlace = new GCNumberScrollPart();
			_tensPlace = new GCNumberScrollPart();
			_hundredsPlace = new GCNumberScrollPart();
			_thousandsPlace = new GCNumberScrollPart();
			
			init();
		}
		
		private function init():void
		{
			// Adjust the position of the NumberScrollParts
			_thousandsPlace.setXY(0, 0);
			_hundredsPlace.setXY(_thousandsPlace.width, 0);
			_tensPlace.setXY(_hundredsPlace.x + _hundredsPlace.width, 0);
			_onesPlace.setXY(_tensPlace.x + _tensPlace.width, 0);
			
			// Add listener to each NumberScrollParts
			_thousandsPlace.addEventListener(GCEvent.VALUE_INCREASE_EVENT, onIncreaseValue);
			_hundredsPlace.addEventListener(GCEvent.VALUE_INCREASE_EVENT, onIncreaseValue);
			_tensPlace.addEventListener(GCEvent.VALUE_INCREASE_EVENT, onIncreaseValue);
			_onesPlace.addEventListener(GCEvent.VALUE_INCREASE_EVENT, onIncreaseValue);
			_thousandsPlace.addEventListener(GCEvent.VALUE_DECREASE_EVENT, onDecreaseValue);
			_hundredsPlace.addEventListener(GCEvent.VALUE_DECREASE_EVENT, onDecreaseValue);
			_tensPlace.addEventListener(GCEvent.VALUE_DECREASE_EVENT, onDecreaseValue);
			_onesPlace.addEventListener(GCEvent.VALUE_DECREASE_EVENT, onDecreaseValue);
			
			
			// Add the NumberScrollParts to the sprite
			this.addChild(_onesPlace);
			this.addChild(_tensPlace);
			this.addChild(_hundredsPlace);
			this.addChild(_thousandsPlace);
		}
		
		//----------------------------------------------------------------------
		//	PUBLIC FUNCTIONS
		//----------------------------------------------------------------------		
		
		/**
		 * Set the maximum value that the user can set the component
		 * to represent.
		 * 
		 * @param newLimit
		 * 		The maximum value that one can reach.
		 */
		public function setLimit(newLimit:int):void
		{	
			if (newLimit > MAX_VALUE)
			{
				newLimit = MAX_VALUE;
			}
			
			_limit = newLimit;
		}
		
		/**
		 * Sets a new value for the component.
		 * 
		 * @param value
		 * 		The new value the component should represent.
		 */
		public function setValue(value:int):void
		{
			if (value <= _limit)
			{
				var thousands:int = value / 1000;
				var hundreds:int = (value % 1000) / 100;
				var tens:int = (value % 100) / 10;
				var ones:int = (value % 10);
				
				/*
				Bit of a hack, we don't need four events firing in this
				case.
				*/
				_thousandsPlace.setValue(thousands, false);
				_hundredsPlace.setValue(hundreds, false);
				_tensPlace.setValue(tens, false);
				_onesPlace.setValue(ones, false);
				
				this._value = value;
				this.dispatchEvent(new Event(GCEvent.VALUE_CHANGED_EVENT));
			}
		}
		
		//----------------------------------------------------------------------
		//	GET FUNCTIONS
		//----------------------------------------------------------------------

		public function get value():int
		{
			return _value;
		}
		
		//----------------------------------------------------------------------
		//	EVENT HANDLERS
		//----------------------------------------------------------------------		
		
		/**
		 * Triggered when one of the values changes. Is called only when the
		 * user clicks on one of the buttons to manually increase/decrease
		 * the value.
		 */ 
		
		private function onIncreaseValue(event:Event):void
		{
			switch(event.currentTarget)
			{
				case _thousandsPlace: 
					_newValue = _value + 1000;
					break;
				case _hundredsPlace: 
					_newValue = _value + 100;
					break;
				case _tensPlace:
					_newValue = _value + 10;
					break;
				case _onesPlace: 
					_newValue = _value + 1;
					break;
				default:
					return;
			}
			checkValidValue(_newValue);
			setValue(_value);
		}
		
		private function onDecreaseValue(event:Event):void
		{
			switch(event.currentTarget)
			{
				case _thousandsPlace: 
					_newValue = _value - 1000;
					break;
				case _hundredsPlace: 
					_newValue = _value - 100;
					break;
				case _tensPlace:
					_newValue = _value - 10;
					break;
				case _onesPlace: 
					_newValue = _value - 1;
					break;
				default:
					return;
			}
			checkValidValue(_newValue);
			setValue(_value);
		}

		//----------------------------------------------------------------------
		//	HELPER FUNCTIONS
		//----------------------------------------------------------------------
		
		private function checkValidValue(newValue:int):Boolean
		{
			if (newValue >= 0 && newValue <= _limit)
			{
				_value = newValue;
				//this.dispatchEvent(new Event(GCEvent.VALUE_CHANGED_EVENT));
				return true;
			}
			else 
			{
				return false;
			}
		}
		
	}
}